/*
   Copyright (c) 2011, 2012, 2015 Mizar Tools Contributors (mizartools.org)

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
/*  Contributors :
 *	2011-02-18 Marco Riccardi - initial implementation
 *	2012-04-09 Marco Riccardi - changed constructor of Mode 
 *                            - implemented reduction registration
 *  2015-01-11 Marco Riccardi - changed reduction (canceled typeList)
 *                            - changed getSchemeList in getElementList
 *
 */
package org.mizartools.dli.utility;

import java.util.HashMap;
import java.util.LinkedList;

import org.mizartools.dli.Abbreviation;
import org.mizartools.dli.Aggregate;
import org.mizartools.dli.AggregateNotation;
import org.mizartools.dli.Antecedent;
import org.mizartools.dli.Antonym;
import org.mizartools.dli.Argeq;
import org.mizartools.dli.Argeqs;
import org.mizartools.dli.ArticleId;
import org.mizartools.dli.Assumptions;
import org.mizartools.dli.Attribute;
import org.mizartools.dli.AttributeNotation;
import org.mizartools.dli.Cluster;
import org.mizartools.dli.ConditionalRegistration;
import org.mizartools.dli.Constructor;
import org.mizartools.dli.DecodedLibraryItem;
import org.mizartools.dli.Definiendum;
import org.mizartools.dli.Definiens;
import org.mizartools.dli.DliException;
import org.mizartools.dli.ExistentialRegistration;
import org.mizartools.dli.Fields;
import org.mizartools.dli.ForgNotation;
import org.mizartools.dli.Format;
import org.mizartools.dli.Formula;
import org.mizartools.dli.Func;
import org.mizartools.dli.Functor;
import org.mizartools.dli.FunctorNotation;
import org.mizartools.dli.IdentifyRegistration;
import org.mizartools.dli.ItemDefinition;
import org.mizartools.dli.ItemId;
import org.mizartools.dli.ItemType;
import org.mizartools.dli.Loci;
import org.mizartools.dli.Locus;
import org.mizartools.dli.Mode;
import org.mizartools.dli.ModeNotation;
import org.mizartools.dli.Parameters;
import org.mizartools.dli.Predicate;
import org.mizartools.dli.PredicateNotation;
import org.mizartools.dli.Prefices;
import org.mizartools.dli.Premisses;
import org.mizartools.dli.ProperDefiniens;
import org.mizartools.dli.Properties;
import org.mizartools.dli.Redefinition;
import org.mizartools.dli.ReductionRegistration;
import org.mizartools.dli.Scheme;
import org.mizartools.dli.Selector;
import org.mizartools.dli.SelectorNotation;
import org.mizartools.dli.Sethood;
import org.mizartools.dli.Structure;
import org.mizartools.dli.StructureNotation;
import org.mizartools.dli.SymbolId;
import org.mizartools.dli.Synonym;
import org.mizartools.dli.Term;
import org.mizartools.dli.TermAdjectiveRegistration;
import org.mizartools.dli.Theorem;
import org.mizartools.dli.Thesis;
import org.mizartools.dli.Type;
import org.mizartools.dli.Verum;
import org.mizartools.dli.Visible;
import org.mizartools.system.ArticleFactory;
import org.mizartools.system.IClusterRegistration;
import org.mizartools.system.utility.DefinientiaSignature;
import org.mizartools.system.utility.NotationsSignature;
import org.mizartools.system.utility.RegistrationsSignature;
import org.mizartools.system.utility.SchemesSignature;
import org.mizartools.system.utility.TheoremsSignature;
import org.mizartools.system.utility.UniqueIdentifier;
import org.mizartools.system.utility.UniqueIdentifierException;

public class ItemFactory {

	private static HashMap<UniqueIdentifier, DecodedLibraryItem> hashMapItem = new HashMap<UniqueIdentifier, DecodedLibraryItem>();
	
	private ItemFactory() {}

	public static DecodedLibraryItem getItem(
			org.mizartools.system.utility.AbstractSignature abstractSignature, 
			org.mizartools.system.xml.Constructor constructor) 
	throws DliException {
		ArticleId articleId = new ArticleId(constructor.getAid());
		ItemType itemType = null;
		ItemDefinition itemDefinition = null;
		LinkedList<Locus> locusList = Adapter.getLocusList(abstractSignature, constructor.getArgTypes());
		Properties properties = Adapter.getProperties(constructor.getProperties());
		Type type = null;
		Redefinition redefinition = Adapter.getRedefinition(abstractSignature, constructor);
		switch (constructor.getKind()) {
		case M :
			type = Adapter.getType(abstractSignature, constructor.getTypList().getFirst());
			itemDefinition = new Mode(locusList, type, properties, redefinition);
			itemType = ItemType.mode; 
			break;
		case R :
			itemDefinition = new Predicate(locusList, properties, redefinition);
			itemType = ItemType.pred; 
			break;
		case K :	
			type = Adapter.getType(abstractSignature, constructor.getTypList().getFirst());
			itemDefinition = new Functor(locusList, type, properties, redefinition);
			itemType = ItemType.func; 
			break;
		case V :
			type = Adapter.getType(abstractSignature, constructor.getTypList().getFirst());
			itemDefinition = new Attribute(locusList, type, redefinition, properties);
			itemType = ItemType.attr; 
			break;
		case G :
			type = Adapter.getType(abstractSignature, constructor.getTypList().getFirst());
			itemDefinition = new Aggregate(locusList, type);
			itemType = ItemType.aggr; 
			break;
		case L :
			Prefices prefices = Adapter.getPrefices(abstractSignature, constructor.getTypList());
			Fields fields = Adapter.getFields(abstractSignature, constructor.getFields());
			itemDefinition = new Structure(locusList, prefices, fields);
			itemType = ItemType.struct; 
			break;
		case U :
			type = Adapter.getType(abstractSignature, constructor.getTypList().getFirst());
			itemDefinition = new Selector(locusList, type);
			itemType = ItemType.sel; 
			break;
		default :
		}
		int nr = constructor.getNr();
		ItemId itemId = new ItemId(articleId, itemType, nr);
		DecodedLibraryItem decodedLibraryItem = new DecodedLibraryItem(itemId, itemDefinition);
		return decodedLibraryItem;
	}

	public static DecodedLibraryItem getItem(
			org.mizartools.system.utility.AbstractSignature abstractSignature,
			org.mizartools.system.xml.Pattern pattern)
		throws DliException {
		ArticleId articleId = new ArticleId(pattern.getAid());
		ItemType itemType = null;
		ItemDefinition itemDefinition = null;
		SymbolId symbolId1 = Adapter.getSymbolId1(pattern);
		Loci loci = Adapter.getLoci(abstractSignature, pattern.getArgTypes());
		Format format = Adapter.getFormat(pattern.getFormat());
		Visible visible = Adapter.getVisible(pattern.getVisible());
		Constructor constructor = Adapter.getConstructor(abstractSignature, pattern);
		Synonym synonym = null; 
		Antonym antonym = null;
		org.mizartools.system.xml.Pattern.Kind kind = pattern.getKind();
		switch (kind) {
		case M :
			if (pattern.getRedefnr() != null) synonym = new Synonym();
			Abbreviation abbreviation = Adapter.getAbbreviation(abstractSignature, pattern.getExpansion());
			itemDefinition = new ModeNotation(symbolId1, loci, format, visible, constructor, abbreviation, synonym);
			itemType = ItemType.modenot; 
			break;
		case R :
			if (pattern.getAntonymic() != null)	antonym = new Antonym();
			if (pattern.getRedefnr() != null) synonym = new Synonym();
			if (antonym != null && synonym != null) synonym = null;
			itemDefinition = new PredicateNotation(symbolId1, loci, format, visible, constructor, antonym, synonym);
			itemType = ItemType.prednot; 
			break;
		case K :
			if (pattern.getRedefnr() != null) synonym = new Synonym();
			SymbolId symbolId2 = Adapter.getSymbolId2(pattern);
			itemDefinition = new FunctorNotation(symbolId1, symbolId2, loci, format, visible, constructor, synonym);
			itemType = ItemType.funcnot; 
			break;
		case V :
			if (pattern.getAntonymic() != null)	antonym = new Antonym();
			if (antonym == null && pattern.getRedefnr() != null) synonym = new Synonym();
			itemDefinition = new AttributeNotation(symbolId1, loci, format, visible, constructor, antonym, synonym);
			itemType = ItemType.attrnot; 
			break;
		case G :
			itemDefinition = new AggregateNotation(symbolId1, loci, format, visible, constructor, synonym);
			itemType = ItemType.aggrnot; 
			break;
		case L :
			itemDefinition = new StructureNotation(symbolId1, loci, format, visible, constructor, synonym);
			itemType = ItemType.structnot; 
			break;
		case U :
			itemDefinition = new SelectorNotation(symbolId1, loci, format, visible, constructor, synonym);
			itemType = ItemType.selnot; 
			break;
		case J :
			itemDefinition = new ForgNotation(symbolId1, loci, format, visible, constructor, synonym);
			itemType = ItemType.forgnot; 
			break;
		default :
		}
		if (itemDefinition == null)	itemDefinition = new ItemDefinition("?");

		int nr = pattern.getNr();
		ItemId itemId = new ItemId(articleId, itemType, nr);

		DecodedLibraryItem decodedLibraryItem = new DecodedLibraryItem(itemId, itemDefinition);
		return decodedLibraryItem;
	}
	
	public static DecodedLibraryItem getItem(
			org.mizartools.system.utility.AbstractSignature abstractSignature, 
			org.mizartools.system.xml.Definiens definiens,
			int relativeNr) 
	throws DliException {
		ArticleId articleId = new ArticleId(definiens.getAid());
		ItemDefinition itemDefinition = null;
		Definiendum definiendum = new Definiendum(Adapter.getItemId(abstractSignature, definiens.getConstrkind(), definiens.getConstrnr()));
		Loci loci = Adapter.getLoci(abstractSignature, definiens.getTypList());
		Visible visible = Adapter.getVisible(definiens.getEssentials());
		Assumptions assumptions = null;
		if (definiens.getFormula() == null) {
			assumptions = new Assumptions(new Verum());	
		} else {
			assumptions = new Assumptions(Adapter.getFormula(abstractSignature, definiens.getFormula(), new VariableId()));	
		}
		ProperDefiniens properDefiniens = Adapter.getProperDefiniens(abstractSignature, definiens.getDefMeaning(), new VariableId());
		itemDefinition = new Definiens(definiendum, loci, visible, assumptions, properDefiniens);
		ItemId itemId = new ItemId(articleId, ItemType.dfs, definiens.getDefnr() - relativeNr);
		DecodedLibraryItem decodedLibraryItem = new DecodedLibraryItem(itemId, itemDefinition);
		return decodedLibraryItem;
	}

	private static DecodedLibraryItem getItemC(
			org.mizartools.system.utility.AbstractSignature abstractSignature, 
			org.mizartools.system.xml.CCluster cCluster) 
		throws DliException {
		ArticleId articleId = new ArticleId(cCluster.getAid());
		ItemDefinition itemDefinition = null;
		Loci loci = Adapter.getLoci(abstractSignature, cCluster.getArgTypes());
		Type type = null;
		if (cCluster.getTyp() != null) type = Adapter.getType(abstractSignature, cCluster.getTyp());
		LinkedList<org.mizartools.system.xml.Cluster> cluster1List = new LinkedList<org.mizartools.system.xml.Cluster>();
		if (cCluster.getCluster1() != null) cluster1List.add(cCluster.getCluster1()); 
		Antecedent antecedent = new Antecedent(Adapter.getAdjectiveList(abstractSignature, cluster1List));
		LinkedList<org.mizartools.system.xml.Cluster> clusterList2 = new LinkedList<org.mizartools.system.xml.Cluster>();
		if (cCluster.getCluster2() != null) clusterList2.add(cCluster.getCluster2()); 
		if (cCluster.getCluster3() != null) clusterList2.add(cCluster.getCluster3()); 
		Cluster cluster = new Cluster(Adapter.getAdjectiveList(abstractSignature, clusterList2));
		itemDefinition = new ConditionalRegistration(loci, antecedent, type, cluster);
		ItemId itemId = new ItemId(articleId, ItemType.condreg, cCluster.getNr());
		DecodedLibraryItem decodedLibraryItem = new DecodedLibraryItem(itemId, itemDefinition);
		return decodedLibraryItem;
	}

	public static DecodedLibraryItem getItemF(
			org.mizartools.system.utility.AbstractSignature abstractSignature, 
			org.mizartools.system.xml.FCluster fCluster) 
		throws DliException {
		ArticleId articleId = new ArticleId(fCluster.getAid());
		Loci loci = Adapter.getLoci(abstractSignature, fCluster.getArgTypes());
		Term term = Adapter.getTerm(abstractSignature, fCluster.getTerm(), new VariableId());
		Type type = null;
		if (fCluster.getTyp() != null) type = Adapter.getType(abstractSignature, fCluster.getTyp());
		LinkedList<org.mizartools.system.xml.Cluster> clusterList = new LinkedList<org.mizartools.system.xml.Cluster>();
		if (fCluster.getCluster1() != null) clusterList.add(fCluster.getCluster1()); 
		if (fCluster.getCluster2() != null) clusterList.add(fCluster.getCluster2()); 
		Cluster cluster = new Cluster(Adapter.getAdjectiveList(abstractSignature, clusterList));
		ItemDefinition itemDefinition = new TermAdjectiveRegistration(loci, cluster, term, type);
		fCluster.getArgTypes();
		ItemId itemId = new ItemId(articleId, ItemType.funcreg, fCluster.getNr());
		DecodedLibraryItem decodedLibraryItem = new DecodedLibraryItem(itemId, itemDefinition);
		return decodedLibraryItem;
	}

	public static DecodedLibraryItem getItemR(
			org.mizartools.system.utility.AbstractSignature abstractSignature, 
			org.mizartools.system.xml.RCluster rCluster) 
	throws DliException {
		ArticleId articleId = new ArticleId(rCluster.getAid());
		Loci loci = Adapter.getLoci(abstractSignature, rCluster.getArgTypes());
		Type type = Adapter.getType(abstractSignature, rCluster.getTyp());
		LinkedList<org.mizartools.system.xml.Cluster> clusterList = new LinkedList<org.mizartools.system.xml.Cluster>();
		if (rCluster.getCluster1() != null) clusterList.add(rCluster.getCluster1()); 
		if (rCluster.getCluster2() != null) clusterList.add(rCluster.getCluster2()); 
		Cluster cluster = new Cluster(Adapter.getAdjectiveList(abstractSignature, clusterList));
		ItemDefinition itemDefinition = new ExistentialRegistration(loci, cluster, type);
		ItemId itemId = new ItemId(articleId, ItemType.exreg, rCluster.getNr());
		DecodedLibraryItem decodedLibraryItem = new DecodedLibraryItem(itemId, itemDefinition);
		return decodedLibraryItem;
	}

	public static DecodedLibraryItem getItem(
			org.mizartools.system.utility.RegistrationsSignature registrationsSignature,
			org.mizartools.system.IClusterRegistration iClusterRegistration) throws DliException {
		if (iClusterRegistration instanceof org.mizartools.system.xml.CCluster) {
			return getItemC(registrationsSignature, (org.mizartools.system.xml.CCluster)iClusterRegistration);
		} else if (iClusterRegistration instanceof org.mizartools.system.xml.FCluster) {
			return getItemF(registrationsSignature, (org.mizartools.system.xml.FCluster)iClusterRegistration);
		} else if (iClusterRegistration instanceof org.mizartools.system.xml.RCluster) {
			return getItemR(registrationsSignature, (org.mizartools.system.xml.RCluster)iClusterRegistration);
		} else {
			throw new DliException();
		}
	}

	public static DecodedLibraryItem getItem(
			org.mizartools.system.utility.AbstractSignature abstractSignature,
			org.mizartools.system.xml.Identify identify) throws DliException {
		ArticleId articleId = new ArticleId(identify.getAid());
		Loci loci = Adapter.getLoci(abstractSignature, identify.getTypList());
	    LinkedList<Argeq> argeqList = new LinkedList<Argeq>();
	    for (org.mizartools.system.xml.Pair pair : identify.getEqArgs().getPairList()) {
	    	Argeq argeq = new Argeq(pair.getX(), pair.getY());
	    	argeqList.add(argeq);
	    }
		Argeqs argeqs = new Argeqs(argeqList);
		Func func1 = (Func)Adapter.getTerm(abstractSignature, identify.getTerm1(), new VariableId());
		Func func2 = (Func)Adapter.getTerm(abstractSignature, identify.getTerm2(), new VariableId());
		ItemDefinition itemDefinition = new IdentifyRegistration(loci, func1, func2, argeqs);
		ItemId itemId = new ItemId(articleId, ItemType.idreg, identify.getNr());
		DecodedLibraryItem decodedLibraryItem = new DecodedLibraryItem(itemId, itemDefinition);
		return decodedLibraryItem;
	}

	public static DecodedLibraryItem getItem(
			org.mizartools.system.utility.AbstractSignature abstractSignature, 
			org.mizartools.system.xml.Theorem theorem,
			TheoremId theoremId,
			TheoremId theoremIdDef) throws DliException {
		String aid = theorem.getAid();
		if (aid == null) aid = abstractSignature.getArticleId();
		ArticleId articleId = new ArticleId(aid);
		Formula formula = Adapter.getFormula(abstractSignature, theorem.getFormula(), new VariableId());
		ItemDefinition itemDefinition = new Theorem(formula);
		ItemType itemType = null;
		int nr = 0;
		switch (theorem.getKind()){
		case D : 
			itemType = ItemType.def;
			theoremIdDef.increment();
			nr = theoremIdDef.getId();
			break;
		case T : 
			itemType = ItemType.th; 
			theoremId.increment();
			nr = theoremId.getId();
			break;
		default :
		}
		if (theorem.getNr() != null) nr = theorem.getNr(); 
		ItemId itemId = new ItemId(articleId, itemType, nr);
		DecodedLibraryItem decodedLibraryItem = new DecodedLibraryItem(itemId, itemDefinition);
		return decodedLibraryItem;
	}

	public static DecodedLibraryItem getItem(
			org.mizartools.system.utility.AbstractSignature abstractSignature,
			org.mizartools.system.xml.Scheme scheme, 
			SchemeId schemeId) throws DliException {
		String aid = scheme.getAid();
		if (aid == null) aid = abstractSignature.getArticleId();
		ArticleId articleId = new ArticleId(aid);
		ItemType itemType = ItemType.sch;
		int nr = 0;
		schemeId.increment();
		nr = schemeId.getId();
		if (scheme.getNr() != null) nr = scheme.getNr(); 
		ItemId itemId = new ItemId(articleId, itemType, nr);
		LinkedList<Type> typeList = Adapter.getParameters(abstractSignature, scheme.getArgTypes());
		Parameters parameters = new Parameters(typeList);
		LinkedList<Formula> formulaList = Adapter.getFormulaList(abstractSignature, scheme.getFormula2List());
		Premisses premisses = new Premisses(formulaList);
		LinkedList<Formula> formula2List = new LinkedList<Formula>();
		formula2List.add(Adapter.getFormula(abstractSignature, scheme.getFormula1(), new VariableId()));
		Thesis thesis = new Thesis(formula2List);
		
		ItemDefinition itemDefinition = new Scheme(itemId.toString(), parameters, premisses, thesis);
		DecodedLibraryItem decodedLibraryItem = new DecodedLibraryItem(itemId, itemDefinition);
		return decodedLibraryItem;
	}

	public static DecodedLibraryItem getItem(UniqueIdentifier uniqueIdentifier) throws DliException {
		if (hashMapItem.containsKey(uniqueIdentifier)){
			return hashMapItem.get(uniqueIdentifier);
		}
		String aid = uniqueIdentifier.aid;
		org.mizartools.system.Article articleXml = ArticleFactory.getInstance().getArticle(aid);
		org.mizartools.system.utility.UniqueIdentifierType type = uniqueIdentifier.type;
		switch (type) {
		case attrnot:
		case funcnot:
		case modenot:
		case prednot:
			if (!articleXml.hasNotations()) throw new DliException();
			NotationsSignature notationsSignature = articleXml.getNotationsSignature();
			for (org.mizartools.system.xml.Pattern pattern : articleXml.getNotations().getPatternList()){
				DecodedLibraryItem decodedLibraryItem = getItem(notationsSignature, pattern);
				UniqueIdentifier uniqueIdentifier1;
				try {
					uniqueIdentifier1 = UniqueIdentifier.getInstance(decodedLibraryItem.getItemId().toString());
				} catch (UniqueIdentifierException e) {
					e.printStackTrace();
					throw new DliException();
				}
				if (hashMapItem.containsKey(uniqueIdentifier1)) {
					throw new DliException();
				} else {
					hashMapItem.put(uniqueIdentifier1, decodedLibraryItem);
				}
			}
			break;
		case sch:
			if (!articleXml.hasSchemes()) throw new DliException();
			SchemesSignature schemesSignature = articleXml.getSchemesSignature();
			SchemeId schemeId = new SchemeId();
			for (org.mizartools.system.IElement element : articleXml.getSchemes().getElementList()){
				if (element instanceof org.mizartools.system.xml.Canceled) {
					schemeId.increment();
				} else if (element instanceof org.mizartools.system.xml.Scheme) {
					org.mizartools.system.xml.Scheme scheme = (org.mizartools.system.xml.Scheme)element;
					DecodedLibraryItem decodedLibraryItem = getItem(schemesSignature, scheme, schemeId);
					UniqueIdentifier uniqueIdentifier1;
					try {
						uniqueIdentifier1 = UniqueIdentifier.getInstance(decodedLibraryItem.getItemId().toString());
					} catch (UniqueIdentifierException e) {
						e.printStackTrace();
						throw new DliException();
					}
					if (hashMapItem.containsKey(uniqueIdentifier1)) {
						throw new DliException();
					} else {
						hashMapItem.put(uniqueIdentifier1, decodedLibraryItem);
					}
					
				} else {
					throw new DliException();
				}
			}
			break;
		case dfs:
			if (!articleXml.hasDefinientia()) throw new DliException();
			DefinientiaSignature definientiaSignature = articleXml.getDefinientiaSignature();
			int relativeNr = 0;
			int nrDefiniens = 0;
			for (org.mizartools.system.xml.Definiens definiens : articleXml.getDefinientia().getDefiniensList()){
				nrDefiniens++;
				relativeNr = definiens.getDefnr() - nrDefiniens;
				DecodedLibraryItem decodedLibraryItem = ItemFactory.getItem(definientiaSignature, definiens, relativeNr);
				UniqueIdentifier uniqueIdentifier1;
				try {
					uniqueIdentifier1 = UniqueIdentifier.getInstance(decodedLibraryItem.getItemId().toString());
				} catch (UniqueIdentifierException e) {
					e.printStackTrace();
					throw new DliException();
				}
				if (hashMapItem.containsKey(uniqueIdentifier1)) {
					throw new DliException();
				} else {
					hashMapItem.put(uniqueIdentifier1, decodedLibraryItem);
				}
			}
			break;
		case def:
		case th:
			if (!articleXml.hasTheorems()) throw new DliException();
			TheoremsSignature theoremsSignature = articleXml.getTheoremsSignature();
			TheoremId theoremId = new TheoremId();
			TheoremId theoremIdDef = new TheoremId();
			for (org.mizartools.system.xml.Theorem theorem : articleXml.getTheorems().getTheoremList()){
				DecodedLibraryItem decodedLibraryItem = ItemFactory.getItem(theoremsSignature, theorem, theoremId, theoremIdDef);
				UniqueIdentifier uniqueIdentifier1;
				try {
					uniqueIdentifier1 = UniqueIdentifier.getInstance(decodedLibraryItem.getItemId().toString());
				} catch (UniqueIdentifierException e) {
					e.printStackTrace();
					throw new DliException();
				}
				if (hashMapItem.containsKey(uniqueIdentifier1)) {
					throw new DliException();
				} else {
					hashMapItem.put(uniqueIdentifier1, decodedLibraryItem);
				}
			}
			break;
		case exreg:
		case funcreg:
			if (!articleXml.hasRegistrations()) throw new DliException();
			RegistrationsSignature registrationsSignature = articleXml.getRegistrationsSignature();
			for (IClusterRegistration iClusterRegistration : articleXml.getRegistrations().getIClusterRegistrationList()){
				DecodedLibraryItem decodedLibraryItem = ItemFactory.getItem(registrationsSignature, iClusterRegistration);
				UniqueIdentifier uniqueIdentifier1;
				try {
					uniqueIdentifier1 = UniqueIdentifier.getInstance(decodedLibraryItem.getItemId().toString());
				} catch (UniqueIdentifierException e) {
					e.printStackTrace();
					throw new DliException();
				}
				if (hashMapItem.containsKey(uniqueIdentifier1)) {
					throw new DliException();
				} else {
					hashMapItem.put(uniqueIdentifier1, decodedLibraryItem);
				}
			}
			break;
		default : 
			throw new DliException(); 
		}
		if (hashMapItem.containsKey(uniqueIdentifier)){
			return hashMapItem.get(uniqueIdentifier);
		} else {
			throw new DliException();
		}
	}

	public static DecodedLibraryItem getItem(
			org.mizartools.system.utility.AbstractSignature abstractSignature,
			org.mizartools.system.xml.Reduction reduction) throws DliException {
		ArticleId articleId = new ArticleId(reduction.getAid());
		Loci loci = Adapter.getLoci(abstractSignature, reduction.getTypList());
		Term term1 = Adapter.getTerm(abstractSignature, reduction.getTerm1(), new VariableId());
		Term term2 = Adapter.getTerm(abstractSignature, reduction.getTerm2(), new VariableId());
		ItemDefinition itemDefinition = new ReductionRegistration(loci, term1, term2);
		ItemId itemId = new ItemId(articleId, ItemType.redreg, reduction.getNr());
		DecodedLibraryItem decodedLibraryItem = new DecodedLibraryItem(itemId, itemDefinition);
		return decodedLibraryItem;
	}

	public static DecodedLibraryItem getItem(
			org.mizartools.system.utility.AbstractSignature abstractSignature,
			org.mizartools.system.xml.Property property)  throws DliException {
		ArticleId articleId = new ArticleId(property.getAid());
		Loci loci = Adapter.getLoci(abstractSignature, property.getArgTypes());
		Type type = Adapter.getType(abstractSignature, property.getTyp());
		ItemDefinition itemDefinition = new Sethood(loci, type);
		ItemId itemId = new ItemId(articleId, ItemType.sethood, property.getNr());
		DecodedLibraryItem decodedLibraryItem = new DecodedLibraryItem(itemId, itemDefinition);
		return decodedLibraryItem;
	}

}
